﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;

namespace ServiceCore.Tool.Pic
{
    public class PicCheckHelper
    {

        private static readonly Random rdm = new Random();
        private static readonly int _width = 100;
        private static readonly int _height = 28;
        private static readonly Color _bgColor = Color.White;
        private static List<Color> _wordColorlist = new List<Color>();

        private static readonly List<string> use_familylist = new List<string>
            {
                "Arial Black",
                "Arial Rounded MT Bold",
                "Batang",
                "BatangChe",
                "Berlin Sans FB",
                "Bernard MT Condensed",
                "Cooper Black",
                "Copperplate Gothic Bold",
                "Dotum",
                "DotumChe",
                "Eras Bold ITC",
                "Eras Demi ITC",
                "EU-DY",
                "EU-F5",
                "EU-F5X",
                "EU-F6",
                "EU-F6X",
                "EU-F7",
                "EU-F7X",
                "EU-F8",
                "EU-F9",
                "EU-F9X",
                "EU-YT2",
                "Franklin Gothic Demi",
                "Franklin Gothic Demi Cond",
                "Franklin Gothic Heavy",
                "Futura Hv",
                "Gill Sans Ultra Bold Condensed",
                "Gulim",
                "GulimChe",
                "Gungsuh",
                "GungsuhChe",
                "Haettenschweiler",
                "Helvetica 65 Medium",
                "Helvetica 95 Black",
                "Helvetica-Black-SemiBold",
                "Helvetica-BoldOblique",
                "Helvetica-Condensed-Black-Se",
                "Helvetica-Roman-SemiB",
                "HelveticaExt-Normal",
                "HelveticaExtObl-Heavy",
                "HelveticaInserat-Roman-SemiB",
                "HelveticaInserat-Roman-SemiBold",
                "HelveticaNeue BlackCond",
                "HelveticaNeue ExtBlackCond",
                "HelveticaNeue MediumExt",
                "HelveticaObl-Heavy",
                "Impact",
                "MingLiU",
                "MingLiU_HKSCS",
                "MS Gothic",
                "MS Mincho",
                "MS PGothic",
                "MS PMincho",
                "MS UI Gothic",
                "PMingLiU",
                "Rockwell Extra Bold",
                "Segoe UI Semibold",
                "Tw Cen MT Condensed Extra Bold",
                "仿宋_GB2312",
                "微软简粗黑",
                "方正大黑_GBK",
                "方正琥珀_GBK",
                "方正粗倩_GBK",
                "方正粗圆_GBK",
                "方正综艺_GBK",
                "方正胖娃_GBK",
                "方正超粗黑_GBK",
                "楷体_GB2312",
            };
        private static readonly FontFamily[] fontFamilyList = FontFamily.Families.Where(f => use_familylist.Contains(f.Name)).ToArray();

        private static readonly string[] CheckList = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }; //, "A", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"

        public static void Initialize()
        {
            List<int> i_list = new List<int> { 0, 1, 2, 5, 6, 7, 9, 13, 19, 25, 27, 44, 47, 48, 49, 53, 54, 58, 59, 60, 61, 62, 63, 64, 66, 67, 69, 76, 77, 79, 92, 93, 94, 95, 97, 103, 105, 107, 108, 121, 123, 127, 130, 136, 137, 138, 139 };
            List<Color> list = new List<Color>();
            Type type = typeof(Color);
            PropertyInfo[] fields = type.GetProperties();
            int i = 0;
            foreach (var item in fields)
            {
                if (item.ToString().IndexOf(".Color") > 0)
                {
                    if (!i_list.Contains(i))
                    {
                        list.Add(Color.FromName(item.Name));
                    }
                    i++;
                }
            }   
            _wordColorlist = list;
        }

        public static Bitmap GetCheckImage(string checkStr)
        {
            var c_index = rdm.Next(_wordColorlist.Count);
            Color p_color = _wordColorlist[c_index];
            Pen p = new Pen(p_color);
            Bitmap img = new Bitmap(_width, _height);
            using (Graphics g = Graphics.FromImage(img))
            {
                g.Clear(_bgColor);
                int fontWidth = _width / checkStr.Length;
                int fontHeight = _height;
                for (int i = 0; i < checkStr.Length; i++)
                {
                    string str = checkStr[i].ToString();
                    int fontFamilyIndex = rdm.Next(0, fontFamilyList.Length);
                    int fontSize = rdm.Next(19, 22);
                    int fontStyleIndex = rdm.Next((int)FontStyle.Regular, (int)FontStyle.Italic + 1);
                    Font font = new Font(fontFamilyList[fontFamilyIndex], fontSize, (FontStyle)Enum.Parse(typeof(FontStyle), fontStyleIndex.ToString()), GraphicsUnit.Point);
                    SizeF size = g.MeasureString(str, font);
                    float x = ((float)fontWidth - size.Width) / (float)2;
                    x = x > 0 && x < size.Width ? x : 0;
                    float y = ((float)fontHeight - size.Height) / (float)3;
                    y = y > 0 && y < size.Height ? y : 0;
                    g.DrawString(str, font, p.Brush, x + (float)(i * fontWidth), y);
                }
                int fx = rdm.Next(0, 2);
                int l_h = rdm.Next(0, _height + 1);
                int r_h = rdm.Next(0, _height + 1);

                //List<Point> plist = new List<Point>();
                //plist.Add(new Point(0, l_h));

                //int p_n = rdm.Next(3, 6);
                //int tmp_b = 0;
                //int tmp_e = _width / 2;
                //for (var i = 0; i < p_n; i++)
                //{
                //    int p_w = rdm.Next(tmp_b, tmp_e);
                //    tmp_b = p_w + 1;
                //    tmp_e = _width - (_width - tmp_b) / 2;
                //    int p_h = rdm.Next(0, _height);
                //    plist.Add(new Point(p_w, p_h));
                //}
                //plist.Add(new Point(_width, r_h));
                //if (fx == 0)
                //{
                //    plist.Add(new Point(_width, 0));
                //    plist.Add(new Point(0, 0));
                //}
                //else
                //{
                //    plist.Add(new Point(_width, _height));
                //    plist.Add(new Point(0, _height));
                //}
                GraphicsPath myGraphicsPath = new GraphicsPath();
                myGraphicsPath.Reset();
                g.SetClip(myGraphicsPath);
                //myGraphicsPath.AddPolygon(plist.ToArray());

                g.Flush();

                for (int i = 0; i < _width; i++)
                {
                    for (int j = 0; j < _height; j++)
                    {
                        if (myGraphicsPath.IsVisible(i, j))
                        {
                            var tmp_color = img.GetPixel(i, j);
                            if (tmp_color.A == p_color.A && tmp_color.B == p_color.B && tmp_color.G == p_color.G && tmp_color.R == p_color.R)
                            {
                                img.SetPixel(i, j, _bgColor);
                            }
                            else
                            {
                                img.SetPixel(i, j, p_color);
                            }
                        }
                    }
                }
            }
            return img;
        }

        public static string GetCheckStr()
        {
            string checkStr = String.Empty;
            for (int i = 0; i < 4; i++)
            {
                checkStr += CheckList[rdm.Next(0, CheckList.Length)];
            }
            return checkStr;
        }

        public static byte[] GetCheckBuff(string checkStr)
        {
            try
            {
                using (Stream sm = new MemoryStream())
                {
                    GetCheckImage(checkStr).Save(sm, ImageFormat.Png);
                    byte[] buff = new byte[sm.Length];
                    sm.Position = 0;
                    sm.Read(buff, 0, buff.Length);
                    sm.Flush();
                    sm.Close();
                    return buff;
                }
            }
            catch
            {
                return null;
            }
        }

        public static string ToBase64(Bitmap bmp)
        {
            try
            {
                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                String strbaser64 = Convert.ToBase64String(arr);
                return strbaser64;
            }
            catch (Exception ex)
            {

                return "";
            }
        }
    }
}
